﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Reflection;

namespace ArgusLight.Fractals2D
{
	/// <summary>
	/// The Baseclass for Fractalcoloring-Methods.
	/// </summary>
	public abstract class Coloring
	{
		/// <summary>
		/// Indicates wether enough data was collected to color the fractal.
		/// </summary>
		public bool IsReady
		{
			get
			{
				return this.Data != null && this.Parameter != null;
			}
		}
		public virtual FractalParameter FractalParameter { get; protected set; }
		public virtual ColoringParameter Parameter { get; set; }
		public virtual ColoringData Data { get; protected set; }
		
		/// <summary>
		/// Returns the color for the point (x, y). This Method must not be called before
		/// <see cref="IsReady"/> is <c>true</c>.
		/// </summary>
		public abstract Color GetColor(int x, int y);

		public Coloring()
		{
			this.Parameter = new ColoringParameter();
		}

		/// <summary>
		/// Resets the collected data. This method must be called before the
		/// new data is collected.
		/// </summary>
		public virtual void Reset(FractalParameter fParameter)
		{
			this.FractalParameter = fParameter.GetCopy();
		}

		public virtual void PostCalculation() { }

		/// <summary>
		/// Initialized the Coloring class with the given paramters and data.
		/// When calling this method on derived classes only the permitted 
		/// subclasses of <see cref="FractalParameter"/>, <see cref="ColoringParameter"/> and <see cref="ColoringData"/>
		/// may be passed.
		/// </summary>
		public void Initialize(FractalParameter fParameter, ColoringParameter cParameter, ColoringData data)
		{
			this.FractalParameter = fParameter;
			this.Parameter = cParameter;
			this.Data = data;
		}

		public Coloring CreateNewInstance()
		{
			Type t = this.GetType();
			Coloring c = (Coloring)Activator.CreateInstance(t);
			return c;
		}
	}
}
